/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package guiExtentions;

import configuration.ConfigurationManager;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.ConvolveOp;
import java.awt.image.Kernel;
import javax.swing.JPanel;

/**
 *
 * @author zalem1
 */
public class JImage extends JPanel {
    private BufferedImage[] Images;
    private int shadowSize = 5;
    private float shadowOpacity = 0.2f;
    private Color shadowColor = Color.BLACK;
    private int previewPictureCount;
    private int gridCellSize = 85;
    
    public JImage() {
        previewPictureCount = ConfigurationManager.GetPreferences().getPreviewPictureCount();
        Images = new BufferedImage[previewPictureCount];            
    }
    
    @Override
    protected void paintComponent(Graphics gc) {
        if (getImage(0) != null)
        {
            Color bgColor = gc.getColor();
            gc.clearRect(0, 0, getWidth(), getHeight());

            for (int imageIndex = 0; imageIndex < previewPictureCount; imageIndex++)
            {
                BufferedImage image = getImage(imageIndex);
                if (image == null) continue;
                
                image = prepareImage(image);
                BufferedImage shaddow = createDropShadow(image);

                int locationW = 0;
                int locationH = 0;
                switch (imageIndex)
                {
                    case 0:
                        locationW = 0;
                        locationH = 0;
                        break;
                    case 1:
                        locationW = gridCellSize;
                        locationH = 0;             
                        break;
                    case 2:
                        locationW = 0;
                        locationH = gridCellSize;
                        break;
                    case 3:
                        locationW = gridCellSize;
                        locationH = gridCellSize;
                        break;
                    case 4:
                        locationW = gridCellSize*2;
                        locationH = 0;                        
                        break;
                    case 5:
                        locationW = gridCellSize*2;
                        locationH = gridCellSize;                        
                        break;
                    case 6:
                        locationW = 0;
                        locationH = gridCellSize*2;                        
                        break;
                    case 7:
                        locationW = gridCellSize;
                        locationH = gridCellSize*2;                        
                        break;
                    case 8:
                        locationW = gridCellSize*2;
                        locationH = gridCellSize*2;                        
                        break;
                }
                
                int paddingW = (gridCellSize - image.getWidth())/2;
                int paddingH = (gridCellSize - image.getHeight())/2;
                
                gc.drawImage(shaddow, locationW + shadowSize + paddingW, locationH + shadowSize + paddingH, this);
                gc.drawImage(image, locationW + paddingW, locationH + paddingH, this);
            }
        }
    }
    
    private BufferedImage scaleImage(BufferedImage original) {
        BufferedImage subject = new BufferedImage(original.getWidth() + shadowSize * 2,
                                                original.getHeight() + shadowSize * 2,
                                                BufferedImage.TYPE_INT_ARGB);
      
        original.getWidth();
        int width = 200;
        int height = original.getHeight()*width/original.getWidth();
      
      
        Graphics2D g2 = subject.createGraphics();
        g2.drawImage(original, 0, 0, width, height, this);
        g2.dispose();
        return subject;
      
    }
    
    private BufferedImage prepareImage(BufferedImage original) {
      BufferedImage subject = new BufferedImage(original.getWidth() + shadowSize * 2,
                                                original.getHeight() + shadowSize * 2,
                                                BufferedImage.TYPE_INT_ARGB);
      Graphics2D g2 = subject.createGraphics();
      g2.drawImage(original, null, shadowSize, shadowSize);
      g2.dispose();
      return subject;
    }
    
    private BufferedImage createDropShadow(BufferedImage image) {
      if (image != null) {
        BufferedImage shadow = new BufferedImage(image.getWidth(),
                                                 image.getHeight(),
                                                 BufferedImage.TYPE_INT_ARGB);
        getBlurOp(shadowSize).filter(createShadowMask(image), shadow);
        return shadow;
      }
      return null;
    }
    
    private BufferedImage createShadowMask(BufferedImage image) 
    { 
        BufferedImage mask = new BufferedImage(image.getWidth(),image.getHeight(),BufferedImage.TYPE_INT_ARGB); 

        Graphics2D g2d = mask.createGraphics(); 
        g2d.drawImage(image, 0, 0, null); 
        // Ar = As*Ad - Cr = Cs*Ad -> extract 'Ad' 
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, shadowOpacity)); 
        g2d.setColor(shadowColor); 
        g2d.fillRect(0, 0, image.getWidth(), image.getHeight()); 
        g2d.dispose(); 
        return mask; 
    }   
    
    private ConvolveOp getBlurOp(int size) {
        float[] data = new float[size * size];
        float value = 1 / (float) (size * size);
        for (int i = 0; i < data.length; i++) {
            data[i] = value;
        }
        return new ConvolveOp(new Kernel(size, size, data));
    }

    /**
     * @return the Image
     */
    public BufferedImage getImage(int index) {
        return Images[index];
    }

    /**
     * @param Image the Image to set
     */
    public void setImage(BufferedImage Image, int index) {
        if (index > -1 && index < previewPictureCount)
            this.Images[index] = Image;
    }

    public void clearImages() {
        for (int imageIndex = 0; imageIndex < Images.length; imageIndex++)
            Images[imageIndex] = null;
    }
}
